﻿<template>
    <div
        v-if="checkDone"
        style="width: 100%; height: 100vh; overflow-x: hidden; overflow-y: auto"
    >
        <template v-if="searchType2 == 'dialog'">
            <my-page-header
                :title="title2"
                :allow-back="allowBack"
                :allow-search="allowSearch2 && !customCtr.show"
                :allow-add="checkAddDone && !customCtr.show"
                :allow-tree="!!cfg.tree"
                @goback="onGoback"
                @search-click="onSearch"
                @add-click="onAdd()"
                @tree-click="treeIsOpen=!treeIsOpen"
                :moreActions="moreActions"
                @action-click="onActionClick"></my-page-header>
        </template>
        <template v-else-if="searchType2 == 'allways'">
            <my-page-header
                :title="title2"
                :allow-back="allowBack"
                :allow-search="false"
                :allow-add="checkAddDone && !customCtr.show"
                :allow-tree="!!cfg.tree"
                @goback="onGoback"
                @add-click="onAdd()"
                @tree-click="treeIsOpen=!treeIsOpen"
                :moreActions="moreActions"
                @action-click="onActionClick"></my-page-header>
            <div v-if="allowSearch2 && !customCtr.show && tbname2" style="text-align: center;border-bottom: 1px solid #ccc;padding: 6px 0;">
                <my-search-bar
                    :tbname="tbname2"
                    v-model="search"
                    @clickSearch="doSearch"
                    :maxSearchItem="10"
                    :excludeSearch="excludeSearch"></my-search-bar>
            </div>
        </template>
        <template v-else>
            <my-page-header
                :title="title2"
                :allow-back="allowBack"
                :allow-search="allowSearch2 && !customCtr.show && !customCtr.hideSearchBar"
                :allow-add="checkAddDone && !customCtr.show"
                :allow-tree="!!cfg.tree"
                @goback="onGoback"
                @search-click="onSearch"
                @add-click="onAdd()"
                @tree-click="treeIsOpen=!treeIsOpen"
                :moreActions="moreActions"
                @action-click="onActionClick"></my-page-header>
            <div
                v-show="allowSearch2 && !customCtr.show && tbname2 && showSearchBar"
                style="text-align: center;border-bottom: 1px solid #ccc;padding-top: 10px;">
                <my-search-bar
                    :tbname="tbname2"
                    v-model="search"
                    @clickSearch="doSearch"
                    :maxSearchItem="10"
                    :excludeSearch="excludeSearch"></my-search-bar>
            </div>
        </template>

        <div style="width: 100%; padding: 4px;" v-if="headerComponent">
            <component :is="headerComponent" ref="headerComponent"/>
        </div>

        <el-tabs v-if="tbsSearch" stretch v-model="tbsSearchValue">
            <el-tab-pane v-for="item in getTbsSearch" 
                :label="getTbsLabel(item.label, item.value)"
                :name="String(item.value)"
                :key="String(item.value)">
                <div v-if="item.header" class="pan-header">
                    {{ getTbsLabel(item.header, item.value) }}
                </div>
            </el-tab-pane>
        </el-tabs>


        <template v-if="!customCtr.show">
            <template v-if="rowComponent" >
                <template v-if="page.groups && groupComponent">
                    <component :is="groupComponent"  :groupKey="g" :records="page.records" v-for="g in page.groups"  :key="g" />
                </template>
                <MyGridBox v-else ref="grid" :columns="columnsNum">
                    <component :is="rowComponent" v-for="row in page.records" :key="row.ID" :row="row" style="width:100%;height:100%;box-sizing: border-box;" />
                </MyGridBox>
            </template>
            <component v-else
                :formData="item"
                v-bind="cell2.attrs"
                :cfg="cell_cfg2"
                :is="cell2.cellType"
                v-for="item in page.records"
                :key="item.ID"
                :title="getCellTitle(item)"
                :label="getCellLabel(item)"
                :icon="getCellIcon(item)"
                :value="getCellValue(item)"
                :tag="getCellTag(item)"
                :tags="getCellTags(item)"
                :actions="cell2.actions"
                :links="cell2_links"
                @click="onEdit(item)"
                @update:formData="updateCellData(item, $event)"
                icon-prefix="mlist-cell-icon"
                center
            />

            <el-empty v-if="page.totalCount == 0" description="没有符合条件的数据" />

            <el-pagination
                :layout=pageLayout
                style="margin-top: 20px;display: flex;flex-wrap: wrap;row-gap: 10px;"
                v-if="page.pageCount > 1"
                background
                :pager-count="$mbh5?5:7" 
                v-model:current-page="page.pageIndex"
                v-model:page-size="page.pageSize"
                :total="page.totalCount" />

            <!-- 自定义工具栏按钮 -->
            <div v-if="search_action2" style="border: 1px solid #ccc;margin-top: 20px;padding: 8px 2px;text-align: center;">
                <el-space wrap>
                    <template v-for="btn in search_action2" :key="btn">
                        <template v-if="btn.label && checkIf(btn.vif)">
                            <el-dropdown v-if="btn.options" split-button :type="btn.type" @command="doClick(btn.click, $event)" @click="doClick(btn.click, $event)">
                                {{ btn.label }}
                                <template #dropdown>
                                    <el-dropdown-menu>
                                        <template v-for="menu in btn.options" :key="menu">
                                            <el-dropdown-item v-if="menu.label != '-'" :command="menu.value" :icon="menu.icon">{{menu.label}}</el-dropdown-item>
                                            <el-dropdown-item v-else divided></el-dropdown-item>
                                        </template>
                                    </el-dropdown-menu>
                                </template>
                            </el-dropdown>
                            <el-button v-else :type="btn.type" :icon="btn.icon" @click="doClick(btn.click, $event)" :disabled="checkDisabled(btn.disabled)">{{ btn.label }}</el-button>
                        </template>
                    </template>
                </el-space>
            </div>
        </template>

        <component
            v-if="customCtr.show"
            :key="customCtr.key"
            :is="customCtr.cmpName"
            ref="cusCmp"
            v-bind="customCtr.attrs"
        >
        </component>

        <my-search-dlg
            ref="dlgSearch"
            :tbname="tbname2"
            :search="search"
            @search="doSearch"
            :excludeSearch="excludeSearch"
        ></my-search-dlg>

        <el-drawer v-if="cfg.tree" v-model="treeIsOpen" direction="ltr" size="100%" title="">
            <template #header>
                <div v-if="treeActions?.length>0" style="">
                    <el-space wrap spacer="|">
                        <template v-for="btn in treeActions" :key="btn">
                            <template v-if="btn.label && checkIf(btn.vif)">
                                <template v-if="btn.options && getOps2(btn.options)">
                                    <el-link  v-for="menu in getOps2(btn.options)" type="menu.type" @click="doClick(btn.click, menu.value)" :disabled="checkDisabled(menu.disabled)">{{menu.label }}</el-link>
                                </template>
                                <el-link v-else :type="btn.type" @click="doClick(btn.click, $event)" :disabled="checkDisabled(btn.disabled)">{{btn.label }}</el-link>
                            </template>
                        </template>
                    </el-space>
                </div>
            </template>
            <el-tree ref="tree" highlight-current 
                :node-key="cfg.tree.idField || 'ID'"
                style="width: 100%;"
                @current-change="selectTreeNode"
                :props="cfg.tree.props" :load="loadTreeNode" lazy>
                <template #default="{ node, data }">
                    <span class="tree-node">
                        <component v-if="cfg.tree.nodeControl" :is="cfg.tree.nodeControl" :node="node" :data="data" />
                        <span v-else>{{ node.label }}</span>
                        <span>
                            <el-link type="primary" @click="treeNodeClick(data)">选择</el-link>
                        </span>
                    </span>
                </template>
            </el-tree>
        </el-drawer>

        <MyFloatButton v-if="allowShowCart"  >
            <el-button v-if="cart_options.length==0 || !cart_count" type="primary" plain round @click="showCart()">
                <el-badge :value="cart_count" class="cart_item" type="primary">
                    <el-icon :size="36" ><ShoppingCart /></el-icon>
                </el-badge>
            </el-button>
            <el-dropdown v-else placement="top-start" @command="showCart" >
                <el-button type="primary" plain round>
                    <el-badge :value="cart_count" class="cart_item" type="primary">
                        <el-icon :size="36" ><ShoppingCart /></el-icon>
                    </el-badge>
                </el-button>
                <template #dropdown>
                    <el-dropdown-menu>
                    <el-dropdown-item v-for="op in cart_options" :command="op.value" :key="op.value">{{ op.label }}</el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
        </MyFloatButton>
    </div>
</template>

<script>
import { nextTick, reactive, ref, resolveComponent, toRaw } from "vue";
import { Server, Utils } from "./main";
import MyGridBox from './MyGridBox.vue';
import MyFloatButton from "./MyFloatButton.vue";

export default {
    name: "MyMListPage",
    props: {
        searchType: {
            type: String,
            default: "dialog",
        },
        tbname: {
            type: String,
            required: true,
        },
        allowAdd: {
            type: Boolean,
            default: true,
        },
        allowSearch: {
            type: Boolean,
            default: true,
        },
        allowEdit: {
            type: Boolean,
            default: true,
        },

        allowBack: {
            type: Boolean,
            default: true,
        },
        //默认的搜索条件
        defaultSearch: Object,
        //子记录编辑界面
        formName: {
            type: String,
            default: "my-form-dlg",
        },
        //页面标题
        label: String,
        //如果ID编辑，还是传入整个记录
        editById: {
            type: Boolean,
            default: true,
        },
        columns: Array, //用于替换dm上定义的列
        excludeSearch: String, //额外排除的搜索字段分号(;)分隔
        title: String,
    },
    provide() {
        return {
            MyListPage: this,
        };
    },
    data() {
        return {
            checkAddDone: false,//检查是否允许添加的结果
            checkDone: false, //检查通过以后才能显示
            cfg: {},
            tbname2: "", //tabs多标签的时候，不同标签可能对应不同的表
            cell_cfg: {},
            cell: {
                title: "Name",
                value: "",
                label: "",
                icon: "",
                cellType: "my-cell",
            },
            cell2: {
                title: "Name",
                value: "",
                label: "",
                icon: "",
                cellType: "my-cell",
            },
            tbsSearch: null,
            tbsSearchValue: "",
            showSearchBar: false,
            search: {},
            page: {
                pageIndex: 1,
                pageCount: 0,
                pageSize: 10,
                totalCount: 0,
                records: [],
            },

            //自定义组件
            customCtr: {
                //是否显示自定义组件
                show: false,
                //是否隐藏搜索栏
                hideSearchBar:false,
                //自定义组件名字
                cmpName: "",
                //自定义组件属性
                attrs: {},
            },
            rowComponent:"",
            groupComponent:"",
            columnsNum:4,
            title2:"",
            cart:[],//购物车
            headerComponent:"",//自定义标题栏组件名称
            treeIsOpen:true,
            treeNode:null,
        };
    },
    created() {
        if (this.tbname == "") return;
        this.initByTbname(this.tbname);
        this.title2 = this.title;
    },
    mounted(){
        $server.delay(50).then(()=>{
            this.treeIsOpen = false
        })
    },
    methods: {
        getOps2(ops){
            if(!ops) return null;
            if(typeof ops=="string"){
                ops = ops.split(/[,;]/g).map(x=>({label:x,value:x}));
            }
            const ops2 = (ops || []).filter(x=>this.checkIf(x.vif));
            if(ops2.length>0){
                return ops2;
            }
            return null;
        },
        getSelected() {
            return [];
        },
        call(action, pm) {
            if (action.indexOf("/") != -1) {
                return $server.call(action, pm, this.$el);
            }
            return $server.doAction(this.tbname, pm, this.$el);
        },
        //打开自定义组件显示
        showCustomCtr(cuscfg) {
            this.customCtr = {
                cmpName: cuscfg.cmpName,
                hideSearchBar: cuscfg.hideSearchBar,
                attrs: cuscfg.attrs,
                key: cuscfg.key || this.tbsSearchValue || cuscfg.cmpName,
                fields: cuscfg.fields,
                formName: cuscfg.formName,
                show: cuscfg.cmpName && cuscfg.cmpName.length > 0,
            };
            if (cuscfg.search) {
                this.search = { ...this.search, ...cuscfg.search };
            }
            if (this.customCtr.show != true) {
                this.loadData(1);
            }
        },
        //关闭自定义组件显示
        hideCustomCtr() {
            this.customCtr.show = false;
        },
        proceGridMethods(m, me) {
            for (let key in m) {
                let func = m[key];
                if (typeof func == "function") {
                    me[key] = func.bind(me);
                    //console.log("bind"+key, me);
                } else {
                    console.log("method定义错误：" + key);
                }
            }
        },
        initByTbname(tb) {
            if (!tb) return;
            this.$server.getDM(tb).then((res) => {
                    this.cell = {
                        title: "Name",
                        value: "",
                        label: "",
                        icon: "",
                        cellType: "my-cell",
                    };
                    this.cell2 = {
                        title: "Name",
                        value: "",
                        label: "",
                        icon: "",
                        cellType: "my-cell",
                    };

                    this.tbname2 = tb;
                    this.cfg = res;
                    this.tb = res;//和MyFormDlg一样，提供一个tb属性
                    this.rowComponent = res?.cell?.rowComponent;
                    this.groupComponent = res?.cell?.groupComponent;
                    this.columnsNum = res?.cell?.columnsNum || 4;
                    this.title2 = this.title || this.cfg.title;

                    if(this.cfg.cell && this.cfg.cell.pageSize && this.cfg.cell.pageSize>10){
                        this.page.pageSize = this.cfg.cell.pageSize;
                    }

                    //把自定义组件注册到页面
                    if (res._Components) {
                        if (!this.$options.components) {
                            this.$options.components = {};
                        }
                        Object.keys(res._Components).forEach((key) => {
                            let cmp = toRaw(res._Components[key]);
                            this.$options.components[key] = cmp;
                        });
                    }

                    if (
                        this.columns &&
                        Array.isArray(this.columns) &&
                        this.columns.length > 0
                    ) {
                        this.cfg.columns = [
                            ...this.cfg.columns,
                            ...this.columns,
                        ];
                    }
                    //传入单元格扩展定义
                    if (res.ext) {
                        if (this.cfg.ext.common) {
                            this.proceGridMethods(this.cfg.ext.common.methods, this);
                        }
                        if (this.cfg.ext.cell) {
                            this.proceGridMethods(this.cfg.ext.cell.methods, this);
                        }
                        let ext = Object.assign(
                            { methods: {}, computed: {}, watch: {} },
                            res.ext.common
                        );
                        if (res.ext.cell) {
                            for (let key in res.ext.cell) {
                                let v = res.ext.cell[key];
                                if (!ext[key]) {
                                    ext[key] = {};
                                }
                                Object.assign(ext[key], v);
                            }
                        }
                        this.cell_cfg = { ...res, ...ext };
                    } else {
                        this.cell_cfg = { ...res };
                    }
                    this.cfg.title = this.label || this.cfg.title;

                    this.cell = { ...this.cell, ...res.cell };
                    this.cell2 = { ...this.cell };
                    let cfgDefaultSearch = this.getDefaultSearch4Cfg(res);
                    this.search = {
                        ...cfgDefaultSearch,
                        ...this.defaultSearch,
                    };

                    this.headerComponent = this.cfg?.cell?.headerComponent;

                    let sorder = localStorage.getItem(`${this.tbname}_sort`);
                    if (sorder) {
                        this.search = { ...this.search, order: sorder };
                    }

                    //直接定义一个custList，取代默认的list显示方式
                    let custList = this.cfg.custList_h5 || this.cfg.custList;
                    if (custList && typeof custList == "object") {
                        this.showCustomCtr(custList);
                    } else {
                        this.tbsSearch =
                            this.cfg.tbsSearch_h5 || this.cfg.tbsSearch;
                        if (this.tbsSearch) {
                            let fd = this.tbsField;

                            if (fd.control == "select" && fd.select && fd.select.cfg && fd.select.cfg.tbname) {
                                //取动态options
                                let moduleName = fd.select.cfg.tbname;
                                let valueField = fd.select.cfg.valueField || "ID";
                                let labelField = fd.select.cfg.labelField || "Name";
                                this.$server.list(moduleName,1,1000,fd.select.cfg.search)
                                    .then((res) => {
                                        var lst = [];
                                        var records = res.records || res;
                                        for (var ix = 0;ix < records.length;ix++) {
                                            var record = records[ix];
                                            var item = {
                                                value: record[valueField],
                                                label: record[labelField],
                                            };
                                            lst.push(item);
                                        }
                                        fd.options = lst;
                                        this.tbsSearchValue = fd.default
                                            ? String(fd.default)
                                            : String(lst[0].value);
                                    });
                            } else {
                                this.tbsSearchValue = fd
                                    ? String(fd.default || "")
                                    : "";
                            }
                            if (!this.tbsSearchValue) {
                                const opts = this.getTbsSearch;
                                if (opts && opts.length > 0) {
                                    this.tbsSearchValue = String(opts[0].value);
                                }
                            }
                        } else {
                            this.loadData(1);
                        }
                    }
                    if(this.onCreated){
                        this.onCreated.apply(this);
                    }
                }).then((res) => {
                    if(this.cfg.tree){
                        //数形结构默认属性
                        this.cfg.tree.props = {
                            label: this.cfg.tree.labelField || "label",
                            children:this.cfg.tree.childrenField || "children",
                            isLeaf: 'leaf',
                            ...this.cfg.tree.props
                        };
                    }
                    //如果 allow段有定义showList，则等待showList执行结果，==true时才显示主界面，否则显示空白
                    if (this.cfg.allow && this.cfg.allow.showList) {
                        if (typeof this.cfg.allow.showList == "function") {
                            var p = this.cfg.allow.showList.apply(this);
                            Promise.resolve(p).then((res1) => {
                                this.checkDone = res1 == true;
                            });
                        } else {
                            this.checkDone = this.cfg.allow.showList == true;
                        }
                    } else {
                        this.checkDone = true;
                    }
                    this.proceAddRule();
                });
        },
        getDefaultSearch4Cfg(res) {
            let msearch = {};
            Utils.getTbSearchFields(res, msearch);
            return msearch;
        },

        onGoback() {
            if (this.$router) {
                this.$router.back(); // replace("/main");
            } else {
                history.back();
            }
        },
        loadData(pageIndex) {
            pageIndex = pageIndex || this.page.pageIndex;
            var pms = { ...this.defaultSearch, ...this.search };

            if (this.tbsFieldSearchCode) {
                pms[this.tbsFieldSearchCode] = this.tbsSearchValue;
            }

            let _call_dt = new Date().getTime();
            this._last_call_dt = _call_dt;
            this.$server
                .list(this.tbname2, pageIndex, this.page.pageSize, pms)
                .then((res) => {
                    //页面初始化的时候可能调用了一次，其它情况（tree初始化的时候又调用了一次），但是返回顺序不一致
                    //只接收最后一次调用的返回值
                    if(_call_dt!=this._last_call_dt)return;
                    
                    if(!res.pageCount){
                        res.pageCount=1;
                    }
                    if(!res.pageSize){
                        res.pageSize = 10;
                    }
                    if(!res.totalCount){
                        res.totalCount = res.records.length;
                    }
                    if(!res.pageIndex){
                        res.pageIndex = 1;
                    }
                    this.page = {...this.page, ...res};
                });
        },
        onSearch() {
            if (this.searchType == "dialog") {
                this.$refs.dlgSearch.open(this.search);
            } else {
                this.showSearchBar = !this.showSearchBar;
            }
        },
        onEdit(row) {
            if(this.tbname==this.tbname2){
                const onRowClick = this.cfg?.cell?.methods?.onRowClick 
                    || this.cfg.ext?.cell?.methods?.onRowClick  
                    || this.cfg.ext?.common?.methods?.onRowClick;

                if (onRowClick) {
                    onRowClick.apply(this, [row]);
                    return;
                }
            }

            //没有定义get方法，就不
            let callCfg = this.cfg.call_h5 || this.cfg.call;
            if (callCfg && !callCfg.get) return;

            if (this.allowEdit2) {
                Server.dlg
                    .edit(this.tbname2, this.editById ? row.ID : row)
                    .then((res) => {
                        this.loadData();
                    });
            } else {
                Server.dlg.view(this.tbname2, this.editById ? row.ID : row);
            }
        },
        onAdd(item) {
            if (!item) {
                item = { ID: 0 };
                Object.keys(this.search).forEach(key => {
                    if (["pageIndex", "pageSize"].indexOf(key) == -1) {
                        let val = this.search[key];
                        if (val) {
                            item[key] = val;
                        }
                    }
                })
            }
            // if (location.search) {
            //     //新增记录的时候，把链接上的参数，传入
            //     let hasparams = false;
            //     var ss = {};
            //     var pms = location.search.substring(1).split("&");
            //     pms.forEach((p) => {
            //         let item = p.split("=");
            //         let key = item[0];
            //         if (key != "create" && key!="id" && key!="ID") {
            //             ss[key] = item[1];
            //             hasparams = true;
            //         }
            //     });
            //     if (hasparams) {
            //         item = { ...item, ...ss };
            //     }
            // }
            let props = { defaultCreate: this.defaultSearch };
            if (this.checkAddDone == false) return;
            let pp = this.checkAddDone;
            if (pp && pp.formName) {
                props.formName = pp.formName;
            }
            Server.dlg.create(this.tbname2, 0, item, props).then((res) => {
                this.loadData();
            });
        },
        doSearch(search) {
            this.search = { ...search };
            this.loadData(1);
        },
        doLoad() {
            this.loadData();
        },
        getCellTitle(item) {
            return this.parseCellValue(item, this.cell2.title);
        },
        getCellLabel(item) {
            return this.parseCellValue(item, this.cell2.label);
        },
        getCellValue(item) {
            return this.parseCellValue(item, this.cell2.value);
        },
        getCellTag(item) {
            return this.parseCellValue(item, this.cell2.tag);
        },
        getCellTags(item) {
            if (this.cell2.tags && this.cell2.tags.startsWith("format_")) {
                return this.cell2.tags;
            }
            let tags = (this.cell2.tags || "")
                .split(";")
                .filter((p) => p.length > 0)
                .map((p) => {
                    return this.parseCellValue(item, p);
                });
            return tags.join(";");
        },
        getCellIcon(item) {
            if (this.cell2.icon) {
                return this.parseCellValue(item, this.cell2.icon) || "empty";
            }
            return null;
        },
        parseCellValue(item, tag) {
            return this.$server.dm_format(this.cfg.columns, item, tag);
        },
        getTbsLabel(lb, val) {
            if (lb && lb.indexOf("${") != -1) {
                return lb.replace(/\$\{([^}]+)\}/g, (t1, field) => {
                    val = String(val);
                    if (val == this.tbsSearchValue) {
                        switch (field) {
                            case "total":
                                let total = this.page.totalCount;
                                return total;
                            default:
                                return field;
                        }
                    } else {
                        return "";
                    }
                });
            }
            return lb;
        },
        updateCellData(item, res) {
            //如果单元格里面改变了绑定的item, 需要做相应的更新，让改变反应到list上来
            //例如：单元格里面做了 提交，等等的操作
            this.loadData();
        },

        doClick(func, event) {
            //let me = this.$refs.cusCmp || this;
            let me = this;
            Utils.doFunc(func, me, event != undefined ? [event] : undefined);
        },
        checkIf(vif, args) {
            if (typeof vif == "function") {
                return vif.apply(this, args);
            }
            return true;
        },
        checkDisabled(vif) {
            if (typeof vif == "function") {
                return vif.apply(this);
            }
            return false;
        },
        onActionClick(action) {
            if (action.click) {
                Utils.doFunc(action.click, this);
            }
        },
        setTitle(title){
            this.title2 = title;
        },
        setShowBack(flag){
            
        },
        proceAddRule() {
            if (this.cfg.allow && this.cfg.allow.add != undefined) {
                if (typeof (this.cfg.allow.add) == "function") {
                    let q = this.cfg.allow.add.apply(this);
                    Promise.resolve(q).then(r=>{
                        this.checkAddDone = r;
                    });
                    return;
                }
                this.checkAddDone = this.cfg.allow.add;
                return;
            }
            this.checkAddDone = this.allowAdd;
        },
        add2Cart(row){
            if(!row)return;

            let item = this.cart.find(x=>x.ID==row.ID);
            if(!item){
                item = {...row, _cart_count:1};
                this.cart.push(item);
            }else{
                item._cart_count++;
            }
        },
        showCart(cmd){
            if(this.cart_count>0){
                let items = this.cart.map(x=>({...x}));
                this.cfg.ShoppingCart.onShowCart.apply(this, [cmd, items]);
            }
        },
        allowAdd2Cart(row){
            if(this.allowShowCart && row && this.cfg.ShoppingCart.allowAdd2Cart){
                return this.checkIf(this.cfg.ShoppingCart.allowAdd2Cart, [row]);
            }
            return false;

        },
        //tree
        selectTreeNode(data,node){
            this.treeNode = data;
        },

        loadTreeNode(node, resolve, reject) {
            let keyField = this.cfg.tree.idField || "ID";
            let pid = node?.data[keyField];
            const d1 = new Date().getTime();
            console.log("loadTreeNode="+d1)
            const resolve1 = (items)=>{
                const d2 = new Date().getTime();
                console.log("resolve="+d2+","+(d2-d1)/1000.0)
                resolve(items)
            }
            if(typeof(this.cfg.tree.loadNode)=="function"){
                // this.cfg.tree.loadNode.apply(this,[node, resolve1, reject]);
                this.cfg.tree.loadNode.apply(this,[node, (items)=>{
                    resolve1(items);
                    if(!pid){
                        nextTick(()=>{
                            //加载跟节点的时候，自动选中根节点
                            let cKey = items[0][keyField];
                            this.$refs.tree.setCurrentKey(cKey);
                            this.treeNodeClick(items[0]);
                        })
                    }
                }, reject]);
                return;
            }
            if(!pid){
                pid = this.search[this.cfg.tree.searchField];
                if(!!pid){
                    $server.get(this.cfg.tree.tbname, pid).then(res=>{
                        resolve([res]);
                        nextTick(()=>{
                            //加载跟节点的时候，自动选中根节点
                            let cKey = res[keyField];
                            this.$refs.tree.setCurrentKey(cKey)
                        })
                    })
                    return;
                }
            }
            let pidField = this.cfg.tree.parentField || "pid";
            let pm = {};
            pm[pidField] = pid;
            
            $server.list(this.cfg.tree.tbname, 1,10000, pm).then(res => {
                let items = res.records || res;
                resolve(items);
            });
        },
        treeNodeClick(data,node,el,e){
            this.treeIsOpen = false;
            if(typeof(this.cfg.tree.onSelectNode)=="function"){
                this.cfg.tree.onSelectNode.apply(this, arguments);
                return;
            }
            if(this.cfg.tree.searchField){
                this.search[this.cfg.tree.searchField] = data[this.cfg.tree.idField || "ID"];
                this.loadData();
            }
        },
        addTreeNode(node, pnode){
            if(this.$refs.tree){
                pnode = pnode || this.$refs.tree?.getCurrentNode();
                this.$refs.tree.append(node, pnode);
            }
        },
        removeTreeNode(node){
            if(this.$refs.tree){
                this.$refs.tree.remove(node);
            }
        },
        updateTreeNode(node){
            if(this.$refs.tree){
                let key = node[this.cfg.tree.idField || "ID"];
                let snode = this.$refs.tree.getNode(key);
                snode.data = node;
                this.$refs.tree.updateKeyChildren(key,node);
            }
        },
        getCurrentTreeNode(){
            if(this.$refs.tree){
                return this.$refs.tree.getCurrentNode();
            }
            return null;
        },

    },
    computed: {
        pageLayout(){
            if(this.page.pageCount>5){
                return "prev, pager, next,total,sizes,jumper";    
            }
            return "prev, pager, next";
        },
        allowShowCart(){
            return this.cfg.ShoppingCart && this.cfg.ShoppingCart.onShowCart;
        },
        cart_count(){
            let count = this.cart.reduce((p,c)=>p + (c._cart_count || 0),0);
            return count>0? count:"";
        },
        cart_options(){
            let ops = (this.cfg.ShoppingCart.options || "").split(";").filter(x=>!!x && x.length>0).map(x=>({label:x,value:x}));
            return ops;
        },
        cell2_links(){
            let links = this.cell2.links || [];
            if(this.allowShowCart){
                links.push({label:"+购物车",type:"success", vif:this.allowAdd2Cart, click:this.add2Cart});
            }
            return links;
        },
        getTbsSearch() {
            if (this.tbsSearch) {
                let fd = this.tbsField;
                if (fd && fd.options) {
                    return fd.options;
                }
            }
            return [];
        },
        allowSearch2() {
            if (!this.allowSearch) return false;

            let searchFields = Utils.getTbSearchFields(this.cfg);
            return (
                searchFields &&
                searchFields.filter((p) => p.control != "hidden").length > 0
            );
        },
        
        allowEdit2() {
            if (this.cfg.allow && this.cfg.allow.edit != undefined) {
                if (typeof this.cfg.allow.edit == "function") {
                    return this.cfg.allow.edit.apply(this);
                }
                return this.cfg.allow.edit;
            }

            return this.allowEdit;
        },
        tbsField() {
            let field = this.tbsSearch;
            if (field && typeof this.tbsSearch == "string") {
                field = this.cfg.columns.filter(
                    (p) => p.code == this.tbsSearch
                )[0];
            }
            return field;
        },
        tbsFieldSearchCode() {
            let field = this.tbsField;

            if (field) {
                return field.searchCode || field.code;
            }
            return null;
        },
        cell_cfg2() {
            return this.cell2.cell_cfg || this.cell_cfg;
        },
        searchType2() {
            if (this.cfg.cell) {
                return this.cfg.cell.searchType || this.searchType;
            }
            return this.searchType;
        },
        search_action2() {
            let acitons = undefined;
            if (this.cfg.search_action) {
                acitons = this.cfg.search_action.filter((p) => {
                    return p.allowH5_bar == true && this.checkIf(p.vif);
                });
                if (acitons.length == 0) {
                    acitons = null;
                }
            }
            return acitons;
        },
        moreActions() {
            let actions = [];
            if (this.cfg.search_action) {
                actions = actions.concat(
                    this.cfg.search_action.filter(
                        (p) =>
                            p.allowH5 == true &&
                            !p.options &&
                            this.checkIf(p.vif)
                    )
                );
            }

            let sortFields = [];
            if (this.cfg.columns) {
                //为可排序字段增加排序处理
                let sortkey = `${this.tbname}_sort`;
                let sorder = this.search.order || localStorage.getItem(sortkey);
                let cField = null;
                let cOrder = null;
                if (sorder) {
                    let _sorder = sorder.split(" ");
                    cField = _sorder[0];
                    cOrder = _sorder[1];
                }

                sortFields = this.cfg.columns
                    .filter((x) => x.sortable == true)
                    .map((x) => {
                        let action = {
                            label: "排序：" + x.label,
                            fieldCode: x.code,
                            click() {
                                let sorder =
                                    action.fieldCode +
                                    " " +
                                    (action.icon == "Top" ? "DESC" : "ASC");
                                localStorage.setItem(sortkey, sorder);
                                this.search = { ...this.search, order: sorder };
                                this.loadData(1);
                            },
                        };
                        if (x.code == cField) {
                            action.icon = cOrder == "DESC" ? "Bottom" : "Top";
                        }
                        return action;
                    });
            }
            if (sortFields.length > 0) {
                actions.push({
                    label: "-",
                });
                actions = actions.concat(sortFields);
            }
            if (actions.length == 0) {
                actions = null;
            }
            return actions;
        },
        //左边树结构
        treeWidth(){
            return this.cfg.tree?.width || '200px';
        },
        treeActions(){
            if(Array.isArray(this.cfg.tree.actions)){
                return this.cfg.tree.actions.filter(x=>this.checkIf(x.vif));
            }
            return null;
        }
    },
    watch: {
        tbsSearchValue(val) {
            if (this.tbsFieldSearchCode) {
                this.search[this.tbsFieldSearchCode] = parseInt(val) || val;
            }

            const opts = this.getTbsSearch;
            let item = opts.filter((p) => p.value == val)[0];
            if (item && item.tbname) {
                this.tbname2 = item.tbname;
            } else {
                this.tbname2 = this.tbname;
            }

            let defaultCell = {
                title: "Name",
                value: "",
                label: "",
                icon: "",
                cellType: "my-cell",
            };

            if (item && item.cell) {
                this.cell2 = { ...defaultCell, ...item.cell };
            } else {
                this.cell2 = { ...defaultCell, ...this.cell };
            }

            let cusobj = item;
            if (item.cus) {
                switch (typeof item.cus) {
                    case "function":
                        cusobj = item.cus.apply(this);
                        break;
                    case "object":
                        cusobj = { ...item.cus };
                        break;
                    case "string":
                        cusobj = { cmpName: resolveComponent(item.cus) };
                        break;
                }
            }

            if (cusobj && typeof cusobj == "object") {
                this.showCustomCtr(cusobj);
            } else {
                this.hideCustomCtr();
                this.loadData(1);
            }
        },
        tbname(val) {
            this.initByTbname(val);
        },
        defaultSearch() {
            //routerview keepalive 的时候， 只有defaultSearch条件变化， 此时要重新加载数据
            let cfgDefaultSearch = this.getDefaultSearch4Cfg(this.cfg);
            this.search = { ...cfgDefaultSearch, ...this.defaultSearch };
            this.loadData(1);
        },
        "page.pageIndex": function () {
            this.loadData();
        },
        "page.pageSize": function (newVal) {
            this.loadData(1);
        },
        'cfg.allow.add':function(newVal){
            if(typeof(newVal)=="function"){
                var p = newVal.apply(this);
                Promise.resolve(p).then(res=>{
                    this.checkAddDone=res==true;
                });
            }else{
                this.checkAddDone = newVal==true;
            }
        },
        'cfg.allow.showList':function(newVal){
            if(typeof(newVal)=="function"){
                var p = newVal.apply(this);
                Promise.resolve(p).then(res1 => {
                    this.checkDone = res1 == true;
                });
            }else{
                this.checkDone = newVal==true;
            }
        }
    },
};
</script>

<style scope>
.el-tabs__item {
    padding: 0 6px !important;
}

.mlist-cell-icon {
    width: 42px;
    height: 42px;
}

.mlist-cell-icon img {
    width: 100%;
    height: 100%;
    border-radius: 10px;
}

.pan-header {
    font-size: larger;
    font-weight: bolder;
    border-bottom: 1px solid #ccc;
    padding: 10px;
    margin: 10px;
}
.cart_item1 {
  margin-top: 10px;
  margin-right: 30px;
}
.el-drawer .el-drawer__body{
    padding:4px;
}
.el-drawer .el-drawer__header{
    margin-bottom: 4px;
    padding: 8px;
    border-bottom: 1px solid #ccc;
}
.tree-node{
    display: flex;
    flex: 1; 
    align-items: center;
    justify-content: space-between;
    padding-right: 8px; 
    border-bottom: 1px dashed #ccc;
}
</style>